#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define KEY 6
char *keyword[KEY] = {"for", "if", "then", "else", "while", "do"};
char id[1024];
int num;
int token;

void lexical(FILE *fp) {
	char x = getc(fp);

	num = 0;
	int i = 0;
	token = 0;
	strcpy(id, "\0");

	//process x
	//process each regex here
	//store the result in global variables id, num, or token
	//in case of backtrack, use
	//ungetc(x, fp);
	while(isspace(x) != 0)
		x = getc(fp);

	while (isdigit(x) != 0)
	{
		num = num * 10 + x - '0';
		if(token != 11)
			token = 11;
		id[i++] = x;
		id[i] = '\0';
		x = getc(fp);
		while(isspace(x) != 0)
			x = getc(fp);
	}

	if (token == 11)
	{
		ungetc(x , fp);
		return;
	}

	if (isalpha(x) != 0)
	{
		id[i++] = x;
		id[i] = '\0';
		token = 10;
		x = getc(fp);
		while(isspace(x) != 0)
			x = getc(fp);
		while(isalnum(x))		
		{
			id[i++] = x;
			id[i] = '\0';
			switch(i)
			{
				case 2:
					if (strcmp(id,keyword[1]) == 0)
					{
						token = 2;
						return;
					}
					if (strcmp(id,keyword[5]) == 0)
					{
						token = 6;
						return;
					}
					break;
				case 3:
					if (strcmp(id,keyword[0]) == 0)
					{
						token = 1;
						return;
					}
					break;
				case 4:
					if (strcmp(id,keyword[2]) == 0)
					{
						token = 3;
						return;
					}
					if (strcmp(id,keyword[3]) == 0)
					{
						token = 4;
						return;
					}
					break;
				case 5:
					if (strcmp(id,keyword[4]) == 0)
					{
						token = 5;
						return;
					}
					break;
			}
			if (token != 10)
			{
				token = 10;
			}
			x = getc(fp);
			// while(isspace(x) != 0)
			// 	x = getc(fp);

		}
	}

	if (token == 10)
	{
		ungetc(x , fp);
		return;
	}

	id[0] = x;
	id[1] = '\0';

	switch(x)
	{
		case '+' :
			token = 13;
			break;
		case '-' :
			token = 14;
			break;
		case '*' :
			token = 15;
			break;
		case '/' :
			token = 16;
			break;
		case '=' :
			token = 25;
			break;
		case ';' :
			token = 26;
			break;
		case '(' :
			token = 27; 
			break;
		case ')' :
			token = 28;
			break;
		case '#' :
			token = 0;
			break;
		case ':' :
			x = getc(fp);
			while(isspace(x) != 0)
				x = getc(fp);
			if (x == '=')
			{
				id[1] = '=';
				id[2] = '\0';
				token = 18;
			}
			else
			{
				ungetc(x,fp);
				token = 17;
			}
			break;
		case '<' :
			x = getc(fp);
			while(isspace(x) != 0)
				x = getc(fp);
			if (x == '=')
			{
				id[1] = '=';
				id[2] = '\0';
				token = 22;
			}
			else if (x == '>')
			{
				id[1] = '>';
				id[2] = '\0';
				token = 21;
			}
			else
			{
				ungetc(x,fp);
				token = 20;
			}
			break;
		case '>' :
			x = getc(fp);
			while(isspace(x) != 0)
				x = getc(fp);
			if (x == '=')
			{
				id[1] = '=';
				id[2] = '\0';
				token = 24;
			}
			else
			{
				ungetc(x,fp);
				token = 23;
			}
			break;
	
	}

	
}

int main(int argc, const char *argv[])
{
	if(argc < 2) {
		printf("insufficient args\n");
		return 1;
	}
	FILE *fp = fopen(argv[1], "r");
	do {
		lexical(fp);
		switch(token) {
			case 10: printf("(id, %s)\n", id); break;
			case 11: printf("(num, %d)\n", num); break;
			case -1: printf("error!\n"); break;
			default: printf("(%d, %s)\n", token, id); 		
		}
	} while(token != 0);
	

	fclose(fp);
	return 0;
}
